; docformat = 'rst'
;
; NAME:
;   ncGet
;
;+
; :Purpose:
;   Get netCDF data from a file
;
; :Categories:
;   Model utilities
;
; :Returns:
;   Variable from netCDF file.  If varname is a string array containing multiple variable names 
;     a structure is returned, containing each of the variables.
;
; :Params:
;   VarName : string variable containing the name of the netCDF variable to be extracted
;   
; :Keywords:
;   FileName : full path of netCDF file
;   Scale_factor : (input) set to TRUE to use netCDF scale_factor attribute (if present)
;   Missing_value : (input) set to TRUE to use netCDF missing_value attribute (if present)
;   Attributes : (output) 2D array containing attribute names and values for all attributes associated with variable
;     (only for single variables at the moment)
;   Units : (output) value contained in 'units' attribute (null string returned if not present)
;
; :Examples:
;    IDL> Result=ncget('VarName', filename='filename')
;
; :History:
;   Written by: Matt Rigby, MIT, May 31st 2011
;
;-
function mr_ncget, varname, filename=ncfile, $
  ;input keywords
  scale_factor=scale_factor, missing_value=missing_value, $
  ;output keywords
  attributes=attributes, units=units, variable_names=variable_names


  compile_opt idl2, hidden
  on_error, 2

  nc1=ncdf_open(ncFile)

  ;Find all variables in NetCDF file
  ncdfInfo=ncdf_inquire(nc1)
  variables=strarr(ncdfInfo.nVars)
  variables_string=''
  for vi=0, n_elements(variables)-1 do begin
    variables[vi]=(ncdf_varinq(nc1, vi)).name
    variables_string=variables_string + ' ' + variables[vi]
  endfor
  
  ;If variable name list is requested, output variable names
  if keyword_set(variable_names) then begin
    return, variables
  endif


  ;Check if variable exists in file
  if total(variables eq varname) eq 0 then begin
    print, "MR_NCGET: Variable " + varname + " doesn't exist"
    message, "Available variables: " + variables_string
  endif

  ;Get variable
  if n_elements(varname) eq 1 then begin

    var_info=ncdf_varinq(nc1, varname[0])
    
    ;Get attributes and units
    if var_info.natts gt 0 then begin
      attributes=strarr(var_info.natts, 2)
      for ai=0, var_info.natts-1 do begin
        attributes[ai, 0]=ncdf_attname(nc1, varname[0], ai)
        ncdf_attget, nc1, varname[0], attributes[ai, 0], att_temp
        str=''
        for n=0, n_elements(att_temp)-1 do str=strcompress(str + string(att_temp[n]))
        attributes[ai, 1]=str
      endfor
      wh=where(StrUpCase(reform(attributes[*, 0])) eq 'UNITS')
      if wh[0] ne -1 then units=reform(attributes[wh, 1])
    endif
  
     ;Get variable
     ncdf_varget, nc1, varname[0], ncget
     if keyword_set(missing_value) then begin
       wh=where(strmatch(StrUpCase(reform(attributes[*, 0])), '*MISSING*') or $
          strmatch(StrUpCase(reform(attributes[*, 0])), '*FILL*'))
       if wh[0] eq -1 then print, 'NCGET: MISSING VALUE ATTRIBUTE NOT FOUND' else begin
         ncdf_attget, nc1, varname[0], attributes[wh[0], 0], mv
         ncget[where(ncget eq mv)]=!values.d_nan
       endelse
     endif
     if keyword_set(scale_factor) then begin
       wh=where(strmatch(StrUpCase(reform(attributes[*, 0])), '*SCALE*'))
       if wh[0] eq -1 then print, 'NCGET: SCALE FACTOR ATTRIBUTE NOT FOUND' else begin
         ncdf_attget, nc1, varname[0], attributes[wh[0], 0], sf
         ncget=ncget*sf
       endelse
     endif
   endif else begin

    for varI=0, n_elements(varname)-1 do begin
      
       ncdf_varget, nc1, varname[varI], vartemp

       if keyword_set(missing_value) then begin
         ncdf_attget, nc1, varname[varI], 'missing_value', mv
         vartemp[where(vartemp eq mv)]=!values.d_nan
       endif
       if keyword_set(scale_factor) then begin
         ncdf_attget, nc1, varname[varI], 'scale_factor', sf
         vartemp=vartemp*sf
       endif

       if varI eq 0 then ncget=create_struct(varname[varI], vartemp) else $
          ncget=create_struct(ncget, varname[varI], vartemp)
          
    Endfor

  endelse

  ncdf_close, nc1

  return, ncget

End
